package org.jeecg.modules.xindian.reconciliation.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.xindian.reconciliation.entity.InsuranceSettlementConfig;
import org.jeecg.modules.xindian.reconciliation.enums.DeleteFlagEnum;
import org.jeecg.modules.xindian.reconciliation.mapper.InsuranceSettlementConfigMapper;
import org.jeecg.modules.xindian.reconciliation.service.IInsuranceSettlementConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import static cn.hutool.core.lang.Assert.notNull;
import static org.jeecg.modules.xindian.reconciliation.enums.DeleteFlagEnum.N;

/**
 * @Description: 保险结算配置
 * @Author: jeecg-boot
 * @Date: 2024-04-11
 * @Version: V1.0
 */
@Service
public class InsuranceSettlementConfigServiceImpl extends ServiceImpl<InsuranceSettlementConfigMapper, InsuranceSettlementConfig> implements IInsuranceSettlementConfigService {
    @Autowired
    private ISysBaseAPI sysBaseAPI;
    @Override
    public boolean save(InsuranceSettlementConfig entity) {
        validateConfig(entity);
        entity.setDeleteFlag(N);
        return super.save(entity);
    }

    @Override
    public boolean updateById(InsuranceSettlementConfig entity) {
        validateConfig(entity);
        return super.updateById(entity);
    }

    private static void validateConfig(InsuranceSettlementConfig entity) {
        //做相关的校验
        Assert.notBlank(entity.getInsurance(),"保险公司不能为空");
        Assert.notNull(entity.getRule(),"结算规则不能为空");
        Assert.notBlank(entity.getCompany(),"结算公司不能为空");
        List<InsuranceSettlementConfig.SettlementConfig> settlementConfigs = entity.getConfigs();
        entity.setSettlementConfig(JSON.toJSONString(settlementConfigs));
        notNull(settlementConfigs, "结算平台配置信息不能为空");
        settlementConfigs.forEach(settlementConfig -> {
            List<String> platform = settlementConfig.getPlatform();
            Assert.notEmpty(platform, "不能为空");
            notNull(settlementConfig.getType(), "结算类型不能为空");
            notNull(settlementConfig.getType(), "结算类型不能为空");
            switch (settlementConfig.getType()) {
                case LEVEL: {
                    InsuranceSettlementConfig.TrendsRateConfig trendsRateConfig = settlementConfig.getTrendsRateConfig();
                    Assert.notNull(trendsRateConfig, "结算平台{}阶梯经纪费比例未配置",platform);
                    checkBetween(trendsRateConfig.getMin().getRate(),BigDecimal.ZERO,BigDecimal.ONE,"最大值的比例值");
                    checkBetween(trendsRateConfig.getMax().getRate(),BigDecimal.ZERO,BigDecimal.ONE,"最小值的比例值");
                    BigDecimal min = trendsRateConfig.getMin().getValue();
                    BigDecimal max = trendsRateConfig.getMax().getValue();
                    Assert.isTrue(max.compareTo(min) > 0, "结算平台{}阶梯费率不能大于最大值",platform);
                    //分阶梯判断
                    AtomicReference<BigDecimal> lastPrice = new AtomicReference<>();
                    trendsRateConfig.getInterval().forEach(it -> {
                        notNull(it.getLgt(),"大于经纪费值不能为空");
                        notNull(it.getLt(),"小于经纪费值不能为空");
                        notNull(it.getRate(),"比例值不能为空");
                        checkBetween(it.getRate(),BigDecimal.ZERO,BigDecimal.ONE,"比例值");
                        Assert.isTrue(it.getLgt().compareTo(it.getLt())<0,"经纪费值区间值需要最大值{}需要大于最小值{}.",it.getLt(),it.getLgt());
                         if(lastPrice.get() !=null){
                             BigDecimal lastPriceBt = lastPrice.get();
                             Assert.isTrue(lastPriceBt.compareTo(it.getLt())==0,"经纪费值上一个区间值最大值{}需要等于当前区间最小值{}.",lastPriceBt,it.getLgt());
                         }
                        lastPrice.set(it.getLt());
                    });
                }
                break;
                case SOLITARY: {
                    BigDecimal decimal = settlementConfig.getFixRate();
                    Assert.checkBetween(decimal, BigDecimal.ZERO, BigDecimal.ONE);
                }
            }
        });
    }

    @Override
    public boolean saveOrUpdate(InsuranceSettlementConfig entity) {
        validateConfig(entity);
        return super.saveOrUpdate(entity);
    }

    public static Number checkBetween(Number value, Number min, Number max, String message) {
        notNull(value);
        notNull(min);
        notNull(max);
        double valueDouble = value.doubleValue();
        double minDouble = min.doubleValue();
        double maxDouble = max.doubleValue();
        if ((valueDouble > minDouble) && (valueDouble < maxDouble)) {
            return value;
        } else {
            throw new IllegalArgumentException(StrUtil.format(message+"需要介于{}和{}之间.", new Object[]{min, max}));
        }
    }

    @Override
    public InsuranceSettlementConfig loadByCompany(String company) {
       return lambdaQuery().eq(InsuranceSettlementConfig::getCompany,company).eq(InsuranceSettlementConfig::getDeleteFlag, N).one();
    }

    @Override
    public List<InsuranceSettlementConfig> queryEnableConfig() {
        return lambdaQuery().eq(InsuranceSettlementConfig::getDeleteFlag,N).list();
    }

    @Override
    public void reBuildPlatformCode() {
        List<InsuranceSettlementConfig> queryEnableConfig = queryEnableConfig();
        queryEnableConfig.forEach(one->{
            List<InsuranceSettlementConfig.SettlementConfig> config  = one.buildConfig();
            config.forEach(dt->{
                List<String>  platforms  =  sysBaseAPI.selectByCode(dt.getArea());
                dt.setPlatform(platforms);
            });
            one.setSettlementConfig(JSON.toJSONString(config));
            updateById(one);
        });
    }
}
